package com.joysuch.wwyt.api.sync.service.impl;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.joysuch.wwyt.api.sync.SyncConstants;
import com.joysuch.wwyt.api.sync.SyncResponse;
import com.joysuch.wwyt.api.sync.bean.BaseSyncCreditCardRecordBean;
import com.joysuch.wwyt.api.sync.service.BaseSyncCreditCardRecordService;
import com.joysuch.wwyt.core.bean.BaseTypeGroupBean;
import com.joysuch.wwyt.core.bean.BaseTypeGroupItemBean;
import com.joysuch.wwyt.core.common.ajax.ResultBean;
import com.joysuch.wwyt.core.common.util.DateTimeUtil;
import com.joysuch.wwyt.core.common.util.SimpleDateFormatCache;
import com.joysuch.wwyt.core.entity.BaseConfig;
import com.joysuch.wwyt.core.entity.BaseCreditCardRecord;
import com.joysuch.wwyt.core.entity.BaseTypeGroup;
import com.joysuch.wwyt.core.entity.BaseTypeGroupItem;
import com.joysuch.wwyt.core.repository.BaseCreditCardRecordDao;
import com.joysuch.wwyt.core.repository.BaseTypeGroupDao;
import com.joysuch.wwyt.core.repository.BaseTypeGroupItemDao;
import com.joysuch.wwyt.core.service.BaseConfigService;
import com.joysuch.wwyt.core.service.BaseTypeGroupItemService;
import com.joysuch.wwyt.core.service.BaseTypeGroupService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Service;
import org.springframework.web.client.RestTemplate;

import java.text.ParseException;
import java.util.*;
import java.util.concurrent.TimeUnit;

@Service
@Slf4j
public class BaseSyncCreditCardRecordServiceImpl implements BaseSyncCreditCardRecordService {

    @Autowired
    private BaseConfigService baseConfigService;

    @Autowired
    private RestTemplate restTemplate;

    @Autowired
    private BaseCreditCardRecordDao baseCreditCardRecordDao;

    @Autowired
    private BaseTypeGroupDao typeGroupDao;

    @Autowired
    private BaseTypeGroupItemDao baseTypeGroupItemDao;

    @Autowired
    private BaseTypeGroupItemService baseTypeGroupItemService;

    @Autowired
    private BaseTypeGroupService baseTypeGroupService;

    @Override
//    @Scheduled(initialDelay = 1000, fixedDelay = 5000)
  //  @Scheduled(cron = "0 0/5 * * * ?")
    public ResultBean syncCreditCardRecord() {
        log.info("卡口信息列表同步Job 开始 ...");
        Set<String> bukrs = SyncConstants.unitCodeMap.keySet();
        List<String> msgList = new ArrayList<>();
        Integer typeFlag = 0;
        for (String companyCode : bukrs) {
            try {
                ResultBean result = syncCreditCardRecordByCompany(companyCode, typeFlag);
                msgList.add(result.getData().toString());
            } catch (Exception e) {
                log.error("卡口信息列表同步出错： companyCode={}", companyCode, e);
            }
        }
        log.info("卡口信息列表同步Job 结束 ...");
        return ResultBean.success(msgList);
    }

    @Override
    public ResultBean syncCreditCardRecordByCompany(String companyCode, Integer typeFlag) {
        String logTitle = getLogTitle(typeFlag);
        BaseConfig config = new BaseConfig();
        if (typeFlag == 0) {
            config = baseConfigService.findConfig(SyncConstants.TENENT_ID_DEFAULT, companyCode, SyncConstants.BASE_CONFIG_CREDIT_CARD_RECORD_LIST_URL);
        } else if (typeFlag == 1) {
            config = baseConfigService.findConfig(SyncConstants.TENENT_ID_DEFAULT, companyCode, SyncConstants.BASE_CONFIG_CAR_RECORD_LIST_URL);
        }

        if (config != null && StringUtils.isNotEmpty(config.getValue())) {
            HttpHeaders header = new HttpHeaders();
            header.setContentType(MediaType.APPLICATION_JSON);
            //set request body
            //获取最大创建时间
            String maxCreateTimeStr = getMaxCreateTimeStr(companyCode, typeFlag, logTitle);
            HttpEntity<String> requestBody = new HttpEntity<String>(maxCreateTimeStr, header);
            Map<String, String> params = new HashMap<>();
            params.put("maxCreateTimeStr", maxCreateTimeStr);
            log.info(logTitle + "信息列表同步Job：url={}, param={}", config.getValue());
            String url = config.getValue() + "?maxCreateTimeStr=" + maxCreateTimeStr;
            SyncResponse response = restTemplate.postForObject(url, requestBody, SyncResponse.class, params);
            if (response.getMsgcode().equals("0")) {
                if (response.getData() == null) {
                    log.info(logTitle + "信息列表同步Job： 获取数据列表为空， URL={}", config.getValue());
                    return ResultBean.success(logTitle + "信息列表同步完成：  共同步0条记录；");
                }
                String data = JSONObject.toJSONString(response.getData());
                JSONObject content = JSONObject.parseObject(data);
                //保存数据
                Integer count = processList(content.getString("content"), companyCode, typeFlag, logTitle);
                return ResultBean.success(logTitle + "信息列表同步结束： 共同步" + count.toString() + "条记录；");
            } else {
                log.error(logTitle + "信息列表同步Job： 接口数据获取失败： {}", response);
                return ResultBean.success(logTitle + "信息列表同步失败：  接口数据获取失败；");
            }
        }
        return ResultBean.success(logTitle + "信息列表同步失败：  同步接口未配置；");
    }

    private Integer processList(String content, String companyCode, Integer typeFlag, String logTitle) {
        if (content == null) {
            return 0;
        }
        List<BaseSyncCreditCardRecordBean> list = JSONArray.parseArray(content, BaseSyncCreditCardRecordBean.class);
        log.info(logTitle + ".... 信息同步Job： 共查询列表 list:{} ....", list.size());
        List<BaseCreditCardRecord> recordList = new ArrayList<>();
        int count = 0;
        Long userTypeId;
        for (BaseSyncCreditCardRecordBean bean : list) {
            if (bean.getOrgCode() == null || !companyCode.equals(bean.getOrgCode())) {
                continue;
            }
            count++;
            BaseCreditCardRecord record = baseCreditCardRecordDao.findByCodeAndOrgCodeAndTypeFlag(bean.getCode(), bean.getOrgCode(), typeFlag);
            if (record != null) {
                continue;
            }
            record = new BaseCreditCardRecord();
            record.setDeleteFlag("0");
            record.setTenentId(SyncConstants.TENENT_ID_DEFAULT);
            record.setOrgCode(bean.getOrgCode());
            //主键
            record.setCode(bean.getCode());
            //服务公司
            record.setSunitName(bean.getSunitname());
            //卡号
            record.setCardCode(bean.getCardNumber());
            //门禁通道
            record.setGuardChannel(bean.getChannelName());
            //刷卡时间
            try {
                record.setSlotCardTime(DateTimeUtil.parseDateTime(bean.getUsetime()));
            } catch (ParseException e) {
                log.error("code:" + bean.getCode() + "刷卡时间转换错误", e);
            }
            //进出标记 1：进，2：出，9：验卡
            record.setInOutTag(getInOutTag(bean.getInout()));
            //刷卡是否成功 1：是，0：否
            record.setCreditCardTag(getCreditCardTag(bean.getFlag()));
            //人员类型 1：访客，2：承揽商，3：公司员工
            userTypeId = getUserTypeMap().get(getUserName(bean.getWorkerType()));
            if (userTypeId == null) {
                //新增字典
                userTypeId = addItem(getUserName(bean.getWorkerType()));
            }
            record.setUserTypeId(userTypeId);
            record.setUserTypeName(getUserName(bean.getWorkerType()));
            //所属公司/承揽商
            record.setCompanyName(bean.getClientName());
            //职号/证件号码
            record.setIdNumber(bean.getUserCode());
            //姓名
            record.setUserName(bean.getUsername());
            //备注说明
            record.setRemark(bean.getRemark());
            record.setCarNumber(bean.getCarNumber());
            //创建时间
            try {
                record.setCreateTime(DateTimeUtil.parseDateTime(bean.getCreateTime()));
            } catch (ParseException e) {
                log.error("code:" + bean.getCode() + "创建时间转换错误", e);
            }
            //"0卡口,1车辆
            record.setTypeFlag(typeFlag);
            recordList.add(record);
            if (recordList.size() >= 100) {
                baseCreditCardRecordDao.saveAll(recordList);
                log.info(".... " + logTitle + "信息同步Job： 已同步卡口信息列表 list:{} ....", recordList.size());
                recordList = new ArrayList<>();
            }

        }
        if (recordList.size() > 0) {
            baseCreditCardRecordDao.saveAll(recordList);
            log.info(".... " + logTitle + "信息同步Job： 已同步卡口信息列表 list:{} ....", recordList.size());
        }
        return count;
    }

    //获取日志标题
    private String getLogTitle(Integer typeFlag) {
        if (typeFlag == null) {
            return "";
        } else if (typeFlag == 0) {
            return "卡口";
        } else if (typeFlag == 1) {
            return "车俩出入";
        } else {
            return "";
        }
    }

    //获取最大创建时间
    private String getMaxCreateTimeStr(String companyCode, Integer typeFlag, String logTitle) {
        Date date;
        Date d = baseCreditCardRecordDao.getMaxCreateTime(companyCode, typeFlag);
        if (d == null) {
            //第一次拉数据
            date = new Date(System.currentTimeMillis() - 5 * 1000);
        } else {
            //获取数据库最大的创建时间-5s
            date = new Date(d.getTime() - 5 * 1000);
        }
        log.info(logTitle + "信息列表最大创建时间：date={}", SimpleDateFormatCache.getYmdhms().format(date));
        return SimpleDateFormatCache.getYmdhms().format(date);
    }

    private String getInOutTag(String string) {
        //进出标记 1：进，2：出，9：验卡
        if (StringUtils.isBlank(string)) {
            return "";
        } else if (string.equals("1")) {
            return "进";
        } else if (string.equals("2")) {
            return "出";
        } else if (string.equals("9")) {
            return "验卡";
        } else {
            return "";
        }
    }

    private String getCreditCardTag(String string) {
        //刷卡是否成功 1：是，0：否
        if (StringUtils.isBlank(string)) {
            return "";
        } else if (string.equals("1")) {
            return "是";
        } else if (string.equals("0")) {
            return "否";
        } else {
            return "";
        }
    }

    private String getUserName(String string) {
        //1：访客，2：承揽商，3：公司员工
        if (StringUtils.isBlank(string)) {
            return "";
        } else if (string.equals("1")) {
            return "访客";
        } else if (string.equals("2")) {
            return "承揽商";
        } else if (string.equals("3")) {
            return "公司员工";
        } else {
            return "";
        }
    }

    private Map<String, Long> getUserTypeMap() {
        Map<String, Long> map = new HashMap<>();
        BaseTypeGroup typeGroup = typeGroupDao.findByName("人员类型");
        List<BaseTypeGroupItem> list = baseTypeGroupItemDao.findByTypeGroupId(typeGroup.getId());
        if (list != null) {
            for (BaseTypeGroupItem d : list) {
                map.put(d.getName(), d.getId());
            }
        }
        return map;
    }

    //增加字典
    private Long addItem(String typeName) {
        if (typeName != null) {
            BaseTypeGroup typeGroup;
            typeGroup = typeGroupDao.findByName("人员类型");
            if (typeGroup == null) {
                //人员类型不存在 新增
                BaseTypeGroupBean groupBean = new BaseTypeGroupBean();
                groupBean.setName("人员类型");
                typeGroup = baseTypeGroupService.addType(groupBean);
            }
            log.info("信息同步Job： 已同步信息列表-新增人员类型 typeId:{}", typeGroup.getId());
            BaseTypeGroupItemBean bean = new BaseTypeGroupItemBean();
            bean.setTypeGroupName("人员类型");
            bean.setTypeGroupId(typeGroup.getId());
            bean.setName(typeName);
            BaseTypeGroupItem item = baseTypeGroupItemService.addItem(bean);
            return item.getId();
        } else {
            return null;
        }
    }
}
